package models

import (
	"github.com/jinzhu/gorm"
	"time"
)

type FeedMeta struct {
	gorm.Model `json:"-"`

	URL              string
	Hash             string
	LastModifiedDate string

	LatestHash             string `json:"-" gorm:"-"`
	LatestLastModifiedDate string `json:"-" gorm:"-"`
}

// 检查是否拉取到最新的feed
// UpToDate checks whether last fetched feed is up to date
func (f FeedMeta) UpToDate() bool {
	return !f.Newly() && f.Hash == f.LatestHash
}

// 检查最新的feed是否过期
func (f FeedMeta) OutDated() bool {
	return !f.Newly() && f.Hash != f.LatestHash
}

// 检查是否抓取过feed
func (f FeedMeta) Newly() bool {
	return f.Hash == ""
}

type CveDetail struct {
	gorm.Model `json:"-"`

	CveID   string

	NvdJSON *NvdJSON // Cwe has CweID
}

type NvdJSON struct {
	gorm.Model  `json:"-"`
	CveDetailID uint `json:"-"`


	CveID        string
	Descriptions []Description

	Cvss2      Cvss2Extra
	Cvss3      Cvss3
	Cwes       []Cwe
	Cpes       []Cpe
	Affects    []Affect
	References []Reference

	// Assigner         string
	Certs            []Cert
	PublishedDate    time.Time
	LastModifiedDate time.Time
}


// CVE来源信息
type Reference struct {
	gorm.Model `json:"-"`
	NvdJSONID  uint `json:"-"`

	Source string
	Link   string `sql:"type:text"`
}

// It holds CERT alerts.
type Cert struct {
	gorm.Model `json:"-"`

	NvdJSONID  uint `json:"-"`

	Title string `sql:"type:text"`
	Link  string `sql:"type:text"`
}

// Affect 含有关于NVD JSNO的 vendor/product/version信息
type Affect struct {
	gorm.Model `json:"-"`
	NvdJSONID  uint `json:"-"`

	Vendor  string
	Product string
	Version string
}

// Cvss3 has CVSS Version 3 info
type Cvss3 struct {
	gorm.Model `json:"-"`
	NvdJSONID  uint `json:"-"`

	VectorString string

	AttackVector          string
	AttackComplexity      string
	PrivilegesRequired    string
	UserInteraction       string
	Scope                 string
	ConfidentialityImpact string
	IntegrityImpact       string
	AvailabilityImpact    string

	BaseScore           float64
	BaseSeverity        string
	ExploitabilityScore float64
	ImpactScore         float64
}

// Cvss2 has CVSS Version 2 info
type Cvss2 struct {
	gorm.Model `json:"-"`

	VectorString          string
	AccessVector          string
	AccessComplexity      string
	Authentication        string
	ConfidentialityImpact string
	IntegrityImpact       string
	AvailabilityImpact    string
	BaseScore             float64

	// NVD JSON and JVN has severity (Not in NVD XML)
	Severity string
}

// Cvss2Extra has extra CVSS V2 info
type Cvss2Extra struct {
	NvdJSONID uint `json:"-"`

	Cvss2
	ExploitabilityScore     float64
	ImpactScore             float64
	ObtainAllPrivilege      bool
	ObtainUserPrivilege     bool
	ObtainOtherPrivilege    bool
	UserInteractionRequired bool
}

// Description has description of the CVE
type Description struct {
	gorm.Model `json:"-"`
	NvdJSONID  uint `json:"-"`

	Lang  string
	Value string `sql:"type:text"`
}


// Cwe has CweID
type Cwe struct {
	gorm.Model `json:"-"`
	NvdJSONID  uint `json:"-"`

	CweID string
}

// Cpe is Child model of Nvd.
// see https://www.ipa.go.jp/security/vuln/CPE.html
// In NVD JSON,
// configurations>nodes>cpe>valunerable: true
type Cpe struct {
	gorm.Model `json:"-"`

	NvdJSONID  uint `json:"-"`

	CpeBase
	EnvCpes []EnvCpe
}

// EnvCpe is a Environmental CPE
// Only NVD JSON has this information.
// configurations>nodes>cpe>valunerable: false
type EnvCpe struct {
	gorm.Model `json:"-"`
	CpeID      uint `json:"-"`

	CpeBase
}

// CpeBase has common args of Cpe and EnvCpe
type CpeBase struct {
	URI             string
	FormattedString string
	WellFormedName  string `sql:"type:text"`
	CpeWFN

	VersionStartExcluding string
	VersionStartIncluding string
	VersionEndExcluding   string
	VersionEndIncluding   string
}

// CpeWFN has CPE Well Formed name informaiton
type CpeWFN struct {
	Part            string
	Vendor          string
	Product         string
	Version         string
	Update          string
	Edition         string
	Language        string
	SoftwareEdition string
	TargetSW        string
	TargetHW        string
	Other           string
}